import "uno.css";

import { ApolloProvider } from "@apollo/client";
import { reactBridge } from "@garfish/bridge-react-v18";
import { ConfigProvider, Spin, message, Modal } from "antd";
import locale from "antd/es/locale/zh_CN";
import moment from "moment";
import { Suspense, useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter as Router } from "react-router-dom";

import App from "./App";
import SetTokenByGarfish from "./Garfish";
import Headers from "./layouts/header";

import "./main.scss";
import "antd/dist/antd.less";
import "moment/dist/locale/zh-cn";

import { createClient } from "~/modules/apollo/graphql-client";
import {
  init as initAppConfig,
  useAppConfig,
} from "~/modules/shared/app-config/index";
import { getContent, setup as setupApiServer } from "~/plugins/api-server";
import { BootstrapContext } from "~/plugins/models";
moment.locale("zh-cn");

const createBootstrapContext = (
  rehydrate: () => Promise<void>
): BootstrapContext => {
  return {
    data_apiServer: createClient({
      ssrMode: false,
      connectToDevTools: false,
      url: "",
      batchEnabled: false,
    }).client,
    rehydrate,
  };
};
interface Props {
  basename?: string;
  props?: {
    token: string;
    user: any;
  };
}

/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable react-hooks/rules-of-hooks */
const Main = ({ basename, props }: Props) => {
  message.config({
    prefixCls: "quiver-message",
  });
  Modal.config({
    rootPrefixCls: "quiver",
  });
  const [isReady, setReady] = useState(false);
  const [content] = useState<BootstrapContext>(
    createBootstrapContext(async () => {
      await initAppConfig();
      return Promise.resolve();
    })
  );
  useEffect(() => {
    setupApiServer(content)
      .then(() => {
        setReady(true);
        content.data_apiServer = getContent().data_apiServer;
      })
      .catch((e) => {
        console.warn("bootstrap error.", e);
      });
  }, []);

  if (!basename) {
    const { contextPath } = useAppConfig();
    basename = contextPath;
  }

  if (!isReady) {
    return null;
  }

  return (
    <ApolloProvider client={content.data_apiServer!}>
      <ConfigProvider prefixCls="quiver" locale={locale}>
        {window.__GARFISH__ ? "" : <Headers />}
        <Suspense
          fallback={<Spin className="spain-loading" tip="Loading..." />}
        >
          <Router basename={basename}>
            <App />
          </Router>
        </Suspense>
      </ConfigProvider>
    </ApolloProvider>
  );
};
if (!window.__GARFISH__) {
  ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
    // <React.StrictMode>
    <Main />
    // </React.StrictMode>,
  );
}

export const provider = reactBridge({
  // 子应用挂载点，若子应用构建成 js ，则不需要传递该值
  el: "#root",
  // 根组件, bridge 会默认传递 basename、dom、props 等信息到根组件
  rootComponent: ({ basename, props }: Props) => {
    props && SetTokenByGarfish(props);
    return Main({ basename });
  },
  // 设置应用的 errorBoundary
  errorBoundary: (e: any) => <div> error: {e}</div>,
});
